package Day_0218.Object;

/**
 * @author zxc
 * @date 2023/02/18 14:59
 **/
public class Equals_Hashcode {
    public static void main(String[] args) {
        /**
         * 谈一谈对于equals和hashcode方法的理解
         * ===》
         * 1.hashCode()是Object类的一个方法，返回一个哈希值。
         * ===》Java中，由于每一个对象都是继承于Object基类的，所以每一个对象都有其对应的hashcode;
         *
         * 2.如果两个对象根据equal()方法比较相等，那么调用这两个对象中任意一个对象的hashCode()方法，必须产生相同的哈希值。
         * ===》即，若是两个对象调用equals方法相等的话，则这两个对象的hashcode值必然是相等的;
         *
         * 3.如果两个对象根据equal()方法比较不相等，那么产生的哈希值不一定相等(碰撞的情况下还是会相等的)
         *
         *
         * ===》
         * 总结 ：
         * （1）若是两个对象的hashcode不相等的话，则代表这两个对象必然是不相同的;
         * （2）若是两个对象的hashcode值相同的话，并不一定代表这两个对象是相同的，因为可能有hash碰撞的情况;
         *
         */

        /**
         * == 和 equals方法 之间的区别
         * ===》
         * 1.== :
         * 它的作用是判断两个对象的地址是不是相等。（即，判断两个对象是不是同一个对象。）
         * (基本数据类型 == 比较的是值，引用数据类型 == 比较的是内存地址)
         *
         * 2.equals() :
         * 它的作用也是判断两个对象是否相等。但它一般有两种使用情况：
         * （1）情况1：类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时，等价于通过“==”比较这两个对象。
         * （2）情况2：类覆盖了 equals() 方法。
         *  一般，我们都覆盖 equals() 方法来两个对象的内容相等；若它们的内容相等，则返回 true (即，认为这两个对象相等)。
         *
         * 3.String中的equals方法是被重写过的，
         * （1）因为object的equals方法是比较的对象的内存地址，而String的equals方法比较的是对象的值。
         * （2）当创建String类型的对象时，虚拟机会在字符串常量池中，查找有没有 已经存在的值 和 要创建的值相同 的对象，
         *  如果有，就把它赋给当前引用。
         *  如果没有，就在常量池中重新创建一个String对象。
         *
         */

        /**
         * 为什么重写equals方法时，必须重写hashCode方法？
         * ===》
         * 1.hashCode()介绍
         * （1）hashCode() 的作用是获取哈希码，也称为散列码；
         * （2）它实际上是返回一个int整数。这个哈希码的作用是 确定该对象在哈希表中的索引位置。
         * （3）hashCode() 定义在JDK的Object.java中，这就意味着，Java中的任何类都包含有hashCode()函数。
         * （4）散列表存储的是键值对(key-value)，它的特点是：
         *  能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码！（可以快速找到所需要的对象）
         *
         * 2.为什么要有 hashCode
         * 我们以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode：
         * （1）当你把对象加入 HashSet 时，HashSet 会先计算对象的 hashcode 值，来判断对象加入的位置，
         *  同时也会与其他已经加入对象的 hashcode 值作比较，
         * （2）如果没有相同的hashcode，HashSet会假设对象没有重复出现。
         * （3）但是如果发现有相同 hashcode 值的对象，这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。
         * （4）如果两者相同，HashSet 就不会让其加入操作成功。
         * （5）如果不同的话，就会重新散列到其他位置。
         * 这样我们就大大减少了 equals 的次数，相应就大大提高了执行速度。
         *
         * 3.hashCode()与equals()的相关规定
         * （1）如果两个对象相等，则hashcode一定也是相同的;
         * （2）两个对象相等，对两个对象分别调用equals方法都返回true;
         * （3）两个对象有相同的hashcode值，它们也不一定是相等的;
         *  因此，equals 方法被覆盖过，则 hashCode 方法也必须被覆盖
         *
         * 4.hashCode() 默认行为是，对堆上的对象产生独特值。
         * 如果没有重写 hashCode()，则该 class 的两个对象无论如何都不会相等（即使这两个对象指向相同的数据）
         *
         * 5.对象的相等与指向他们的引用相等，两者有什么不同？
         * （1）对象的相等 比的是内存中存放的内容是否相等;
         * （2）引用相等 比较的是他们指向的内存地址是否相等;
         *
         */
    }
}
